試想一個情況,今天如果有一個表單想隨時保存使用者填寫的資料,能夠他跳去別的頁面或者不小心按到重新整理時依然能夠取回他所填的資料。
直覺來說可能會透過像是 localStorage **、**sessionStorage 等等之類瀏覽器內建的儲存用的 API 來達成這個功能。
但我又不太喜歡直接在 UI 層的地方直接寫與 web storage 溝通的邏輯,那可能又要透過 global state 的 library 讓他們互相同步,那這樣子 UI 層只需要更新 global state 就好。
雖然這樣子很工整但總覺得為了一個頁面的暫存功能要費那麼大的力氣就會覺得有那麼一點煩,所以這時候 Svelte 提供了一個 API :Snapshot
顧名思義感覺是跟狀態或者 context 相關的功能。
首先我們只要在 +page.svelte
使用了 export const snapshot
即可
<script lang="ts">
import type { Snapshot } from './$types';
let formData = $state({
email: '',
name: ''
});
export const snapshot: Snapshot<typeof formData> = {
capture: () => formData,
restore: (value) => (formData = value)
};
</script>
<label>
Email:
<input id="email" bind:value={formData.email} />
</label>
<label>
Name:
<input id="name" bind:value={formData.name} />
</label>
它必須包含兩個 property 分別是 capture
及 restore
但基本上寫法是固定的, capture
是一個回傳要記住的 state ,restore
則是將 value
更新到 state 上。這邊需要額外注意的是 <input/>
(當然其他元件要有)必須要寫明 id
。
可以看出來就算我一直重新整理,這兩個 <input/>
還是能維持剛剛所填寫的資料,但它還有更厲害的功能。
沒錯,它可以隨著瀏覽器紀錄 restore
對應的資料。
還是跟最前面提到的 web storage 有關,它是使用 session storage 達成的,當打開 dev tools 後就會發現我們剛剛的資料都在這裡面了。
那你可能又會好奇那它又是怎麼知道該拿回哪一份資料呢?沒錯就是我們剛剛提到的瀏覽器紀錄,也就是 history
這個瀏覽器 API,當我們將 history 給 console.log
出來後會發現 SvelteKit 將 timestamp 寫進 history.state
,所以它才知道我切換頁面時該取回哪一份資料。
總結來說,雖然我們關掉 tab 後這些資料就會消失了,但如果我們的資料並不需要持久化儲存的話我覺得 Snapshot
已經是一個相當好的暫存方案了。
https://30days-for-svelte5.pages.dev/